package com.smart.parking.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.smart.parking.service.LoginLogService;
import com.smart.parking.service.UserService;
import com.smart.parking.utils.*;
import com.smart.parking.vo.UserVO;
import org.dozer.Mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.smart.parking.mapper.UserMapper;
import com.smart.parking.entity.UserEntity;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    @Value("${spring.aes.miyao}")
    private String miyao;

    //iv加盐
    @Value("${spring.aes.iv}")
    private String iv;

    @Value("${spring.accessKey.id}")
    private String accessKeyId;

    @Value("${spring.accessKey.secret}")
    private String accessKeySecret;

    @Autowired
    private Mapper dozerMapper;

    @Autowired
    private LoginLogService loginLogService;


    //定义日志
    private final static Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    //定义RedisTemplate操作组件
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                new QueryWrapper<UserEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 发送验证码
     *
     * @return boolean
     */
    @Override
    public boolean senMsgPhone(String phone) {
        //随机生成验证码
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, 5)));
        //调用发送验证码的方法
        SendSmsResponse sendSmsResponse = MsgUtils.sendMsg(phone, code, accessKeyId, accessKeySecret);
        //判断是否发送成功
        assert sendSmsResponse != null;
        if ("OK".equals(sendSmsResponse.getBody().getCode())) {
            //验证码存入redis缓存，有效期180秒
            redisTemplate.opsForValue().set(phone, code, 180L, TimeUnit.SECONDS);
            log.info("发送验证码成功");
            return true;
        }
        return false;
    }

    /**
     * 用户账号登录
     *
     * @param userName 用户名
     * @param passWord 密码
     * @return boolean
     */
    @Override
    public boolean userLogin(String userName, String passWord) {
        //根据用户名查询用户
        UserEntity userEntity = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("user_name", userName));
        //用户不存在
        if (userEntity == null) {
            return false;
        }
        //对比密码是否正确
        if (MD5Util.getMd5Plus(passWord).equals(userEntity.getPassword())) {
            //登录成功
            StpUtil.login(userEntity.getUserId());
            log.info("登录成功");
            //新增登录日志
            loginLogService.addLoginLog(userEntity.getUserId(),new Date());
            return true;
        }
//        return AESUtils.getEncryption(miyao, iv, passWord).equals(userEntity.getPassword());
        return false;
    }

    /**
     * 用户手机号登录
     *
     * @param phone 手机号
     * @param code  验证码
     * @return boolean
     */
    @Override
    public boolean userPhoneLogin(String phone, String code) {
        //判断验证码是否过期
        Boolean existKey = redisTemplate.hasKey(phone);
        if (Boolean.FALSE.equals(existKey)) {
            return false;
        }
        //判断验证码是否正确
        String codeRedis = redisTemplate.opsForValue().get(phone);
        if (!Objects.equals(codeRedis, code)) {
            return false;
        }
        //根据用户名查询用户
        UserEntity userEntity = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("phone", phone));
        if (userEntity == null) {
            return false;
        }

        //登录成功
        StpUtil.login(userEntity.getUserId());
        log.info("登录成功");
        loginLogService.addLoginLog(userEntity.getUserId(),new Date());
        return true;
    }

    /**
     * 用户注册
     *
     * @param userVO 用户VO
     * @return boolean
     */
    @Override
    public boolean userRegister(UserVO userVO) {
        //判断验证码是否过期
        Boolean existKey = redisTemplate.hasKey(userVO.getPhone());
        if (Boolean.FALSE.equals(existKey)) {
            return false;
        }
        //判断验证码是否正确
        String code = redisTemplate.opsForValue().get(userVO.getPhone());
        if (!Objects.equals(code, userVO.getCode())) {
            return false;
        }
        UserEntity userEntity = dozerMapper.map(userVO, UserEntity.class);
        //添加用户
        int insert = baseMapper.insert(userEntity);
        //判断是否添加成功
        if (insert > 0) {
            //注册成功直接登录
            log.info("注册成功");
            return this.userLogin(userEntity.getUserName(), userEntity.getPassword());
        }
        return false;
    }

    /**
     * 用户更新
     *
     * @param userEntity 用户
     * @return boolean
     */
    @Override
    public boolean userUpdate(UserEntity userEntity) {
        int update = baseMapper.updateById(userEntity);
        if (update > 0) {
            log.info("更新成功!");
            return this.userLogin(userEntity.getUserName(), userEntity.getPassword());
        }
        return false;
    }

}
